# This code is part of LINKEQ.
#
# (C) Copyright LINKE 2023.
#
# This code is licensed under the Apache License, Version 2.0. You may
# obtain a copy of this license in the LICENSE.txt file in the root directory
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.
#
# -*- coding: utf-8 -*-
# @Time    : 2023/9/12 11:09
# @Author  : HFALSH @ LINKE
# @File    : swin_compiling.py
# @IDE     : PyCharm
import copy
import os
# from quantumcircuit import QuantumCircuit
from qiskit import QuantumCircuit


def circuit_len(schedule):
    """
    Find the depth of a swp schedule using IBM qiskit QuantumCircuit.depth()
    Args:
        schedule: the execution swap schedule

    Returns: the length of the schedule

    """
    circuit = QuantumCircuit(16)
    for item in schedule:
        if item != -1:
            circuit.cx(item[0], item[1])
            circuit.cx(item[1], item[0])
            circuit.cx(item[0], item[1])
    return circuit.depth()


def map2map_swp_cancelling(path):
    swp_schedule = []
    data = []
    with open(file=path) as f:
        data = f.readlines()[3:-5]
        f.close()
    for line in data:
        if line != '\n':
            gates = line.split('\n')[0].split('   ')
            # print(gates)
            for gate in gates:
                gate_name = gate.split(' ')[0]
                if gate_name == 'swp':
                    involved_qubits = gate.split(' ')[1:]
                    # print(gate)
                    # print(involved_qubits)
                    qubits = [int(item) for item in involved_qubits]
                    swp_schedule.append(qubits)

    print(swp_schedule)
    # sample_schedule = swp_schedule[7:10]
    sample_schedule = copy.deepcopy(swp_schedule)
    # print(circuit_len(sample_schedule))
    for i in range(len(sample_schedule)):
        qubits = sample_schedule[i]
        if qubits == -1:
            continue
        print("checking: ", end='')
        print(qubits)
        for j in range(len(sample_schedule) - i - 1):
            print(sample_schedule[i + j + 1])
            if sample_schedule[i + j + 1] == -1:
                continue
            if qubits[0] in sample_schedule[i + j + 1] or qubits[1] in sample_schedule[i + j + 1]:
                # print(sample_schedule[i+j+1])
                if qubits[0] in sample_schedule[i + j + 1] and qubits[1] not in sample_schedule[i + j + 1]:
                    break
                elif qubits[1] in sample_schedule[i + j + 1] and qubits[0] not in sample_schedule[i + j + 1]:
                    break
                else:
                    sample_schedule[i] = -1
                    sample_schedule[i + j + 1] = -1
                    print("--------")
                    break
    return sample_schedule

if __name__ == '__main__':
    path = '../qasm-benchmark/Shor/shor_a8.qasm'
    swp_schedule = []
    data = []
    with open(file=path) as f:
        data = f.readlines()[3:-5]
        f.close()

    for line in data:
        if line != '\n':
            gates = line.split('\n')[0].split('   ')
            # print(gates)
            for gate in gates:
                gate_name = gate.split(' ')[0]
                if gate_name == 'swp':
                    involved_qubits = gate.split(' ')[1:]
                    # print(gate)
                    # print(involved_qubits)
                    qubits = [int(item) for item in involved_qubits]
                    swp_schedule.append(qubits)

    print(swp_schedule)
    # sample_schedule = swp_schedule[7:10]
    sample_schedule = copy.deepcopy(swp_schedule)
    # print(circuit_len(sample_schedule))
    for i in range(len(sample_schedule)):
        qubits = sample_schedule[i]
        if qubits == -1:
            continue
        print("checking: ", end='')
        print(qubits)
        for j in range(len(sample_schedule) - i - 1):
            print(sample_schedule[i + j + 1])
            if sample_schedule[i + j + 1] == -1:
                continue
            if qubits[0] in sample_schedule[i + j + 1] or qubits[1] in sample_schedule[i + j + 1]:
                # print(sample_schedule[i+j+1])
                if qubits[0] in sample_schedule[i + j + 1] and qubits[1] not in sample_schedule[i + j + 1]:
                    break
                elif qubits[1] in sample_schedule[i + j + 1] and qubits[0] not in sample_schedule[i + j + 1]:
                    break
                else:
                    sample_schedule[i] = -1
                    sample_schedule[i + j + 1] = -1
                    print("--------")
                    break
    count = 0
    for item in sample_schedule:
        if item != -1:
            count += 1
    print(count)
    for i in range(len(sample_schedule)):
        print(swp_schedule[i], sample_schedule[i])
    print(circuit_len(swp_schedule))
    print(circuit_len(sample_schedule))
